package com.qingsong.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qingsong.dto.*;
import com.qingsong.entity.RolePermission;
import com.qingsong.entity.Permission;
import com.qingsong.entity.Role;
import com.qingsong.exception.ServiceException;
import com.qingsong.mapper.PermissionMapper;
import com.qingsong.mapper.RoleMapper;
import com.qingsong.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author qingsong
 */
@Service
@CacheConfig(cacheNames = "role")
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;


    @CacheEvict(allEntries = true)
    @Override
    public int insert(RoleInsertDTO roleInsertDTO) {
        Role role = BeanUtil.copyProperties(roleInsertDTO,Role.class);
        role.setDeleted(0);
        role.setCreated(LocalDateTime.now());
        role.setUpdated(LocalDateTime.now());
        int result = roleMapper.insert(role);
        if(result <= 0){
            throw new ServiceException("数据库添加失败!");
        }
        return result;
    }

    @Cacheable(key = "#id", condition = "#id != null", unless = "#result == null")
    @Override
    public Role selectById(Long id) {
        Role result = roleMapper.selectById(id);
        if(ObjectUtil.isEmpty(result)){
            throw new ServiceException("ID不存在!");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int updateById(RoleUpdateDTO roleUpdateDTO) {
        Role role = BeanUtil.copyProperties(roleUpdateDTO, Role.class);

        // 设置默认值
        role.setCreated(null);
        role.setUpdated(LocalDateTime.now());
        // DB修改
        int result = roleMapper.updateById(role);
        if (result <= 0) {
            throw new ServiceException("DB修改失败");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int logicDeleteById(Long id) {
        roleMapper.existsRoleId(id);
        // todo 查询该记录是否被引用
        int result = roleMapper.logicDeleteById(id);
        if(result <= 0){
            throw new ServiceException("数据库逻辑删除失败!");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int logicDeleteByIds(List<Long> ids) {
        roleMapper.existsEmpIds(ids);
        int result = roleMapper.logicDeleteByIds(ids);
        if(result <= 0){
            throw new ServiceException("数据库批量逻辑删除失败!");
        }
        return result;
    }

    @Cacheable(key = "#root.methodName", unless = "#result == null ")
    @Override
    public List<Role> list() {
        return roleMapper.list();
    }

    @Cacheable(key = "#root.methodName + ':' + " + "#pageDTO.getPageNum() + ':' + " + "#pageDTO.getPageSize()", unless = "#result == null ")
    @Override
    public PageInfo<Role> page(PageDTO pageDTO) {
        PageHelper.startPage(pageDTO.getPageNum(), pageDTO.getPageSize());
        return new PageInfo<>(roleMapper.list());
    }

    @Cacheable(key = "#root.methodName + ':' + " +
            "#dto.getTitle() + ':' + " +
            "#dto.getPageNum() + ':' + " +
            "#dto.getPageSize()", unless = "#result == null ")
    @Override
    public PageInfo<Role> pageLikeTitle(RolePageDTO dto) {
        //开启分页
        PageHelper.startPage(dto.getPageNum(),dto.getPageSize());
        //数据分页
        return new PageInfo<>(roleMapper.listLikeTitle(dto.getTitle()));
    }

    @Cacheable(key = "#root.methodName + ':' + #id", condition = "#id != null", unless = "#result == null ")
    @Override
    public List<Permission> getPermissions(Long id) {
        return permissionMapper.selectByRoleId(id);
    }

    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updatePermissions(RoleUpdatePermissionsDTO dto) {
        Long id = dto.getId();
        List<Long> permissionIds = dto.getPermissionIds();

        //删除该角色的全部中间表记录
        permissionMapper.loginDeleteByRoleId(id);

        //循环添加权限列表
        for(Long permissionId: permissionIds){
            RolePermission rolePermission = new RolePermission();
            rolePermission.setFkRoleId(id);
            rolePermission.setFkPermissionId(permissionId);
            rolePermission.setDeleted(0);
            rolePermission.setCreated(LocalDateTime.now());
            rolePermission.setUpdated(LocalDateTime.now());
            if(permissionMapper.insertRolePermission(rolePermission) <= 0){
                throw new ServiceException("添加权限失败");
            }
        }
        return 1;
    }

}
